package main.SQL;

import main.MainApp;
import main.Trees.ProjectNode;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;


public class FillSQLProjectModel  {

    private ProjectNode root;
    private Connection connSQL;
    private HashMap<Integer, ProjectNode> wbsMap;
    private ArrayList<ProjectNode> wbsList;

    public FillSQLProjectModel () {
    }

    public ProjectNode run() {

        try {
            this.connSQL = MsSQLConnect.ConnectDB("Factage");

            this.root = MainApp.curProject;
            root.setAllowChildren(true);
            root.setName(root.getName() + " [ROOT]");

            fillProjectTree();
            addResources();

            connSQL.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return root;
    }

    public ProjectNode newRoot(ProjectNode root) {

        try {
            this.connSQL = MsSQLConnect.ConnectDB("Factage");

            this.root = root;
            this.root.setAllowChildren(true);
            this.root.setName(root.getName() + " [ROOT]");

            fillProjectTree();
            addResources();

//            System.out.println("root childCount" + root.getChildCount());

            connSQL.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return root;
    }

    private void fillProjectTree() throws SQLException {

        Statement stmt = connSQL.createStatement();

        //region Загружаем WBS из SQL
        wbsMap = new HashMap<>();
        wbsList = new ArrayList<>();
        wbsMap.put(root.getWbsId(), root);

        ResultSet rs = stmt.executeQuery("select * from [wbs] where db_name = '" + root.getDbName() + "' and proj_id = " + root.getId() + "ORDER BY [wbs_parent_id] ASC, [seq_num] ASC" );

        while (rs.next()) {
            ProjectNode curWbs = new ProjectNode(rs, "wbs");
            wbsMap.put(rs.getInt("wbs_id"), curWbs);
            wbsList.add(curWbs);
        }
        //endregion

//        rs.close();
//        stmt.close();

        addWbsHierarchy();

        //region Загружаем работы из SQL и привязываем к WBS
        HashMap<Integer, ProjectNode> taskMap = new HashMap<>();
        rs = stmt.executeQuery("select * from [task] where db_name = '" + root.getDbName() + "' and proj_id = " + root.getId() + "ORDER BY wd_code ASC, task_code ASC" );

        while (rs.next()) {
            ProjectNode task = new ProjectNode(rs, "task");
            taskMap.put(task.getId(), task);
            if (!wbsMap.containsKey(task.getParentId())) System.out.println("Отсутствует WBS id = " + task.getParentId());
            if (wbsMap.containsKey(task.getParentId())) wbsMap.get(task.getParentId()).add(task);
        }

//        rs.close();
//        stmt.close();

        MainApp.taskMap = taskMap;
        //endregion

        rs = stmt.executeQuery("SELECT \n" +
                "\tacc.short_name,\n" +
                "\taca.task_id\n" +
                "\n" +
                "\tFROM [Factage].[dbo].[actv_code_assign] as aca\n" +
                "\t\tleft join [Factage].[dbo].[task] as t on aca.task_id = t.task_id\n" +
                "\t\tleft join [Factage].[dbo].[actv_code] as acc on acc.[actv_code_id] = aca.[actv_code_id]\n" +
                "  \n" +
                "\twhere aca.db_name = '" + root.getDbName() + "' and aca.proj_id = " + root.getId());

        while (rs.next()) {
            if (taskMap.containsKey(rs.getInt("task_id"))) taskMap.get(rs.getInt("task_id")).setConstrCode(rs.getString("short_name"));
        }

        rs.close();
        stmt.close();
    }

    private void addWbsHierarchy() {

        for (ProjectNode curWbs : wbsList) {
            if (curWbs.getParentId() == root.getWbsId()) {
                root.add(curWbs);
            } else {
                wbsMap.get(curWbs.getParentId()).add(curWbs);
            }
        }

        for (ProjectNode curWbs : wbsList) {
            curWbs.setName(curWbs.getName()+" [WBS"+(curWbs.getPath().length-2)+"]");
        }
    }

    private void addResources() throws SQLException {

        Statement stmt = connSQL.createStatement();

        //region Загружаем ресурсы из SQL
        HashMap<String, SQLRsrc> rsrcMap = new HashMap<>();
        ResultSet rs = stmt.executeQuery("select * from [rsrc] where db_name = '" + root.getDbName() + "' AND (rsrc_short_name LIKE 'PV%' OR rsrc_short_name = 'MR' OR rsrc_short_name = 'T' OR rsrc_short_name = 'MECH'  OR rsrc_short_name LIKE 'ОБС%' OR rsrc_short_name LIKE 'МК%' OR rsrc_short_name LIKE 'ТХМ%' OR rsrc_short_name LIKE 'ТИ%' OR rsrc_short_name LIKE 'АЗО%' OR rsrc_short_name LIKE 'МЕХ%' OR rsrc_short_name LIKE 'ЭС%' OR rsrc_short_name LIKE 'КИПА%')" );

        while (rs.next()) {
            rsrcMap.put(rs.getString("rsrc_short_name"), new SQLRsrc(rs));
        }
        MainApp.rsrcMap = rsrcMap;
        //endregion

        //region Загружаем назначения ресурсов из SQL
        boolean lostRsrcs = false;
        rs = stmt.executeQuery("select * from [task_rsrc] as tr left join rsrc as r on r.rsrc_id = tr.rsrc_id where tr.db_name = '" + root.getDbName() + "' and tr.proj_id = " + root.getId());
        while (rs.next()) {
            if (MainApp.taskMap.containsKey(rs.getInt("task_id")))
                MainApp.taskMap.get(rs.getInt("task_id")).getRsrc().add(new SQLTaskRsrc(rs));
            else
                lostRsrcs = true;
        }

        if (!lostRsrcs) System.out.println("Проект содержит назначения ресурсов для отсутствующих работ!");
        //endregion

        rs.close();
        stmt.close();
    }

    public void setRoot(ProjectNode root) {
        this.root = root;
    }
}
